package com.demo.woziqi;

import com.demo.woziqi.dao.UserDAO;
import com.demo.woziqi.entity.User;
import com.demo.woziqi.massageImp.GameOverNewMassage;
import com.demo.woziqi.massageImp.NewGameMessage;
import com.demo.woziqi.massageImp.RegretChessMessage;
import com.demo.woziqi.server.GameThread;
import com.demo.woziqi.util.GameConstant;
import com.demo.woziqi.util.GameUtil;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.scene.shape.StrokeLineCap;
import javafx.scene.text.Font;
import javafx.scene.text.FontPosture;
import javafx.scene.text.FontWeight;
import javafx.stage.FileChooser;
import javafx.stage.Stage;

import java.io.File;
import java.io.IOException;
import java.util.Optional;

/**
 * @Author 宋明松
 * @Version V1.0.0
 * @Date 2022-05-16
 * 初始化棋盘按钮，
 * 以及按钮的鼠标监听
 */
public class GameLister {
    private Button btnReStart; // 重新开始按钮
    private Button btnSave;// 保存棋谱按钮
    private Button btnPrint;// 打印棋谱按钮
    private Button btnRegret;// 悔棋按钮
    private Button btnExit;// 退出按钮

    private Button myResBtn; // 我的对战
    private Button btnPrevious; // 上一步
    private Button btnNext; // 下一步
    private Button btnOut; // 退出
    private Button btnAll; // 一件复盘
    private static Label integralText;
    private static Label winText;
    private static Label loseText;
    private static Label drawText;
    private static Label allText;

    /**
     * 初始化棋盘，及按钮
     */
    public void getCheckerboard(Pane pane, Stage stage) {
        getLable(pane); // 联机模式右侧信息面板
        this.btnReStart = new Button("重开一局");
        this.btnSave = new Button("保存棋谱");
        this.btnPrint = new Button("打印棋谱");
        this.btnRegret = new Button("悔       棋");
        this.btnExit = new Button("退       出");
        this.myResBtn = new Button("对战记录");
        /*
         * 按钮节点定位
         * */
        if (GameConstant.pattern != 2) { // 联机模式的按钮使用此布局
            btnReStart.setLayoutX(GameConstant.MARGIN + GameConstant.LINE_DISTANCE * 2);
            btnReStart.setLayoutY(GameConstant.HEIGHT - 130);
            btnSave.setLayoutX(GameConstant.MARGIN + GameConstant.LINE_DISTANCE * 4);
            btnSave.setLayoutY(GameConstant.HEIGHT - 130);
            btnPrint.setLayoutX(GameConstant.MARGIN + GameConstant.LINE_DISTANCE * 6);
            btnPrint.setLayoutY(GameConstant.HEIGHT - 130);
            btnRegret.setLayoutX(GameConstant.MARGIN + GameConstant.LINE_DISTANCE * 8);
            btnRegret.setLayoutY(GameConstant.HEIGHT - 130);
            btnExit.setLayoutX(GameConstant.MARGIN + GameConstant.LINE_DISTANCE * 10);
            btnExit.setLayoutY(GameConstant.HEIGHT - 130);
            myResBtn.setLayoutX(GameConstant.MARGIN + GameConstant.LINE_DISTANCE * 6);
            myResBtn.setLayoutY(GameConstant.HEIGHT - 130);
        } else { // 个人，人机模式使用此布局
            btnReStart.setLayoutX(GameConstant.WIDTH - 35);
            btnReStart.setLayoutY(GameConstant.HEIGHT - 330);
            btnSave.setLayoutX(GameConstant.WIDTH + 70);
            btnSave.setLayoutY(GameConstant.HEIGHT - 330);
            myResBtn.setLayoutX(GameConstant.WIDTH + 20);
            myResBtn.setLayoutY(GameConstant.HEIGHT - 270);
            btnRegret.setLayoutX(GameConstant.WIDTH - 35);
            btnRegret.setLayoutY(GameConstant.HEIGHT - 210);
            btnExit.setLayoutX(GameConstant.WIDTH + 70);
            btnExit.setLayoutY(GameConstant.HEIGHT - 210);
        }
        /*
         * 初始化悔棋中的功能按钮
         * */
        this.btnPrevious = new Button("上一步");
        this.btnNext = new Button("下一步");
        this.btnOut = new Button("退   出");
        this.btnAll = new Button("全复盘");
        /*
         * 打印棋谱中的功能按钮定位
         * */
        btnPrevious.setLayoutX(GameConstant.WIDTH - 90);
        btnPrevious.setLayoutY(GameConstant.HEIGHT - GameConstant.LINE_DISTANCE * 13);
        btnNext.setLayoutX(GameConstant.WIDTH - 90);
        btnNext.setLayoutY(GameConstant.HEIGHT - GameConstant.LINE_DISTANCE * 10);
        btnOut.setLayoutX(GameConstant.WIDTH - 90);
        btnOut.setLayoutY(GameConstant.HEIGHT - GameConstant.LINE_DISTANCE * 12);
        btnAll.setLayoutX(GameConstant.WIDTH - 90);
        btnAll.setLayoutY(GameConstant.HEIGHT - GameConstant.LINE_DISTANCE * 11);

        pane.getChildren().add(btnReStart); // 添加重新开始按钮
        pane.getChildren().add(btnSave); // 添加保存棋谱按钮
        if (GameConstant.pattern != 2) { // 联机模式屏蔽打印棋谱按钮
            pane.getChildren().add(btnPrint); // 添加打印棋谱按钮
        }
        if (GameConstant.pattern == 2) {
            pane.getChildren().add(myResBtn); // 添加我的对战
        }
        pane.getChildren().add(btnRegret); // 添加悔棋按钮
        pane.getChildren().add(btnExit); // 添加退出按钮


        /*
         * 定位线（四个边）
         * */
        Line lineR = new Line(60, 60, GameConstant.WIDTH - 60, 60);
        lineR.setStroke(Color.BROWN);
        lineR.setStrokeWidth(6);
        lineR.setStrokeLineCap(StrokeLineCap.BUTT);
        Line lineR1 = new Line(60, GameConstant.HEIGHT - 160, GameConstant.WIDTH - 60, GameConstant.HEIGHT - 160);
        lineR1.setStroke(Color.BROWN);
        lineR1.setStrokeWidth(6);
        Line lineC = new Line(60, 60, 60, GameConstant.HEIGHT - 160);
        lineC.setStroke(Color.BROWN);
        lineC.setStrokeWidth(6);
        Line lineC1 = new Line(GameConstant.WIDTH - 60, 60, GameConstant.WIDTH - 60, GameConstant.HEIGHT - 160);
        lineC1.setStroke(Color.BROWN);
        lineC1.setStrokeWidth(6);

        pane.getChildren().add(lineR); // 添加线条
        pane.getChildren().add(lineR1);
        pane.getChildren().add(lineC);
        pane.getChildren().add(lineC1);
        /*
         * 循环画出棋盘
         * */
        for (int i = 0; i < GameConstant.LINE_NUM; i++) { // 循环画线
            Line lineX = new Line(GameConstant.MARGIN, GameConstant.MARGIN + GameConstant.LINE_DISTANCE * i, GameConstant.MARGIN + (GameConstant.LINE_DISTANCE * (GameConstant.LINE_NUM - 1)), GameConstant.MARGIN + GameConstant.LINE_DISTANCE * i); //初始化横线 x轴不变，y加五十
            Line lineY = new Line(GameConstant.MARGIN + GameConstant.LINE_DISTANCE * i, GameConstant.MARGIN, GameConstant.MARGIN + GameConstant.LINE_DISTANCE * i, GameConstant.MARGIN + (GameConstant.LINE_DISTANCE * (GameConstant.LINE_NUM - 1))); //初始化竖线 y轴不变，x加五十
            lineX.setStroke(Color.BROWN);
            lineX.setStrokeWidth(2);
            lineY.setStroke(Color.BROWN);
            lineY.setStrokeWidth(2);
            pane.getChildren().add(lineX); // 添加线条
            pane.getChildren().add(lineY);
        }
        /*
         * 棋盘中的四个定位点
         * */
        Circle circleBlack1 = new Circle(3 * GameConstant.LINE_DISTANCE + GameConstant.MARGIN, 11 * GameConstant.LINE_DISTANCE + GameConstant.MARGIN, 5, Color.BROWN); // 初始化五个定位点
        Circle circleBlack2 = new Circle(3 * GameConstant.LINE_DISTANCE + GameConstant.MARGIN, 3 * GameConstant.LINE_DISTANCE + GameConstant.MARGIN, 5, Color.BROWN);
        Circle circleBlack3 = new Circle(11 * GameConstant.LINE_DISTANCE + GameConstant.MARGIN, 3 * GameConstant.LINE_DISTANCE + GameConstant.MARGIN, 5, Color.BROWN);
        Circle circleBlack4 = new Circle(11 * GameConstant.LINE_DISTANCE + GameConstant.MARGIN, 11 * GameConstant.LINE_DISTANCE + GameConstant.MARGIN, 5, Color.BROWN);
        Circle circleBlack5 = new Circle(7 * GameConstant.LINE_DISTANCE + GameConstant.MARGIN, 7 * GameConstant.LINE_DISTANCE + GameConstant.MARGIN, 5, Color.BROWN);
        pane.getChildren().add(circleBlack1); // 添加定位点
        pane.getChildren().add(circleBlack2);
        pane.getChildren().add(circleBlack3);
        pane.getChildren().add(circleBlack4);
        pane.getChildren().add(circleBlack5);
        buttonLister(pane, stage); // 初始化鼠标监听方法
    }

    public static void getLable(Pane pane) { // 联机模式右侧 信息展示面板
        if (GameConstant.pattern == 2) {
            Label userText = new Label("欢迎您：" + GameConstant.user.getUsername()); // 用户提示
            Label IPText = new Label("您的IP：" + GameConstant.WIpText);
            Label portText = new Label("启动端口：" + GameConstant.WDkText);
            integralText = new Label("剩余积分：" + GameConstant.user.getIntegral());

            Label regtimeText = new Label("账号注册时间：\n\n" + GameConstant.user.getRegtime().substring(0, 16)); // 用户提示
            winText = new Label("赢  局：" + GameConstant.user.getWin_count() + " 局");
            loseText = new Label("输  局：" + GameConstant.user.getLose_count() + " 局");

            drawText = new Label("和  局：" + GameConstant.user.getDraw_count() + " 局"); // 用户提示
            allText = new Label("总场数：" + GameConstant.user.getAll_count() + " 场");
            /*
             * 积分位置定位
             * */
            Font fonts = Font.font("KaiTi", FontWeight.BOLD, FontPosture.ITALIC, 18);
            userText.setLayoutX(GameConstant.WIDTH - 20);
            userText.setLayoutY(GameConstant.MARGIN);
            userText.setFont(fonts);
            pane.getChildren().add(userText);
            IPText.setLayoutX(GameConstant.WIDTH - 20);
            IPText.setLayoutY(GameConstant.MARGIN + 50);
            IPText.setFont(fonts);
            pane.getChildren().add(IPText);
            portText.setLayoutX(GameConstant.WIDTH - 20);
            portText.setLayoutY(GameConstant.MARGIN + 100);
            portText.setFont(fonts);
            pane.getChildren().add(portText);
            integralText.setLayoutX(GameConstant.WIDTH - 20);
            integralText.setLayoutY(GameConstant.MARGIN + 150);
            integralText.setFont(fonts);
            pane.getChildren().add(integralText);
            regtimeText.setLayoutX(GameConstant.WIDTH - 20);
            regtimeText.setLayoutY(GameConstant.MARGIN + 200);
            regtimeText.setFont(fonts);
            pane.getChildren().add(regtimeText);

            /*
             * 赢局数，输局数，和局数，总局数，定位
             * */
            winText.setLayoutX(GameConstant.WIDTH - 20);
            winText.setLayoutY(GameConstant.MARGIN + 350);
            winText.setFont(fonts);
            pane.getChildren().add(winText);
            loseText.setLayoutX(GameConstant.WIDTH - 20);
            loseText.setLayoutY(GameConstant.MARGIN + 400);
            loseText.setFont(fonts);
            pane.getChildren().add(loseText);
            drawText.setLayoutX(GameConstant.WIDTH - 20);
            drawText.setLayoutY(GameConstant.MARGIN + 450);
            drawText.setFont(fonts);
            pane.getChildren().add(drawText);
            allText.setLayoutX(GameConstant.WIDTH - 20);
            allText.setLayoutY(GameConstant.MARGIN + 500);
            allText.setFont(fonts);
            pane.getChildren().add(allText);
            /*
             * 设置颜色
             * */
            userText.setTextFill(Color.BROWN);
            IPText.setTextFill(Color.BROWN);
            portText.setTextFill(Color.BROWN);
            integralText.setTextFill(Color.BROWN);
            regtimeText.setTextFill(Color.BROWN);
            winText.setTextFill(Color.BROWN);
            loseText.setTextFill(Color.BROWN);
            drawText.setTextFill(Color.BROWN);
            allText.setTextFill(Color.BROWN);
        }
    }

    /**
     * 按钮事件处理方法
     */
    private void buttonLister(Pane pane, Stage stage) {
        UserDAO userDAO = new UserDAO();
        this.btnReStart.setOnMouseClicked(e -> { // 重新开始点击事件,清除pane中的所有元素，并重写绘制节点，并加载鼠标点击事件
            User user = new User();
            if (GameConstant.pattern == 2) { // 联机模式处理方法体
                user.setId(GameConstant.user.getId());
                if (GameConstant.isEnd) { // 对局结束
                    GameUtil.sendMessage(new GameOverNewMassage()); // 发送新局消息
                    // 清除发送程序的面板
                    GameLister gameLister = new GameLister();
                    GameConstant.chess.clear(); // 清除list中的棋子
                    GameConstant.isEnd = false; // 移除结束判断
                    pane.getChildren().clear(); // 清除面板中所有元素

                    GameFightStage.isPlay = true;
                    GameFightStage.isBlack = true;
                    // todo 点击重开按钮
                    if (GameConstant.isEnd) {
                        userDAO.userAllNum(user); // 更改对局数
                    }
                    User u = userDAO.getNumMsg(user); // 查询对局数，以及积分
                    GameConstant.user.setAll_count(u.getAll_count());
                    gameLister.getCheckerboard(pane, stage);// 重写绘制节点，并加载鼠标点击事件
                    return;
                }
                GameUtil.sendMessage(new NewGameMessage()); // 发送新局消息
                // 到消息处理线程清除面板，确保同步
            } else { // 其他模式重开
                GameLister gameLister = new GameLister();
                GameConstant.chess.clear(); // 清除list中的棋子
                GameConstant.isEnd = false; // 移除结束判断
                pane.getChildren().clear(); // 清除面板中所有元素
                gameLister.getCheckerboard(pane, stage);// 重写绘制节点，并加载鼠标点击事件
            }
        });
        this.btnExit.setOnMouseClicked(e -> { // 退出按钮事件处理
            GameConstant.isEnd = false;
            if (GameConstant.chess.size() != 0) { // 棋盘上还有棋子,提示需要保存当前棋谱
                GameUtil.chessNum = 0; // 棋子数清零
                GameConstant.chess.clear(); // 棋子数清零

                Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
                alert.setHeaderText("需要保存当前棋谱吗？");
                //显示对话框
                Optional<ButtonType> result = alert.showAndWait();
                if (result.get() == ButtonType.OK) { // 点击确定执行
                    GameUtil.isWriteFile(stage); // 保存棋谱
                }
                if (GameConstant.pattern == 2) { // 联机模式关闭窗口
                    if (result.get() == ButtonType.OK) { // 点击确定执行
                        stage.close();
                        GameInputPortAndIPStage.inputStage.close();
                        try {
                            GameThread.serverSocket.close(); //TODO 关闭连接
                        } catch (IOException ioException) {
                            ioException.printStackTrace();
                        }
                    }
                }
                stage.close(); // 关闭当前窗口
                GoApplicationStage.stage.show(); // 显示程序模式选择窗口
            } else { // 没有棋子直接关闭
                if (GameConstant.pattern == 2) { // 联机模式关闭窗口
                    try {
                        GameThread.serverSocket.close();
                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                    }
                    stage.close(); // 关闭当前窗口
                    GameConstant.serverSocketIsClosed = false;// 服务器连接关闭
                    GameConstant.chess.clear(); // 棋子数清零
                    GameInputPortAndIPStage.inputStage.close(); // 关闭信息录入窗口
                    GoApplicationStage.stage.show(); // 显示程序模式选择窗口
                } else {
                    stage.close(); // 关闭当前窗口
                    GameConstant.chess.clear(); // 棋子数清零
                    GoApplicationStage.stage.show();// 显示程序模式选择窗口
                }
            }
        });
        this.btnRegret.setOnMouseClicked(e -> { // 悔棋按钮事件处理
            if (GameConstant.pattern == 2) { // 联机模式悔棋
                if (GameFightStage.isPlay) { // 为true时：还没落子，不能悔棋
                    return;
                }
                GameUtil.sendMessage(new RegretChessMessage()); // 发送悔棋消息给服务器线程
                if (!GameConstant.isAgreeRegret) { // 处理服务器线程传来的消息
                    System.out.println("对方拒绝悔棋！！！");// TODO
                }
                // 到消息处理线程清除面板，确保同步
            } else {
                GameUtil.regretChess(pane); // 其他模式悔棋
            }
        });

        this.btnSave.setOnMouseClicked(e -> { // 保存棋谱，鼠标点击事件
            // 判断对局是否已经分出胜负
            if (!GameConstant.isEnd) { // 当前对局未结束
                Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
                alert.setHeaderText("当前对局还未分出胜负，您仍要保存吗？");
                //显示对话框
                Optional<ButtonType> result = alert.showAndWait();
                if (result.get() == ButtonType.OK) { // 点击确定执行
                    GameUtil.isWriteFile(stage); // 保存棋谱
                }
            } else { // 当前对局结束
                GameUtil.isWriteFile(stage); // 保存棋谱
            }
        });
        this.myResBtn.setOnMouseClicked(e -> {
            GameUserHistoryStage gameUserHistoryStage = new GameUserHistoryStage();
            gameUserHistoryStage.show(); // 显示对战记录日志窗口
        });
        this.btnPrint.setOnMouseClicked(e -> { // 打印棋谱，鼠标点击事件
            GameConstant.pattern = 0; // 模式更改为个人对战模式
            if (GameConstant.chess.size() != 0) { // 棋盘上还有棋子
                Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
                alert.setHeaderText("需要保存当前棋谱吗？");
                //显示对话框
                Optional<ButtonType> result = alert.showAndWait();
                if (result.get() == ButtonType.OK) { // 点击确定执行
                    GameUtil.isWriteFile(stage); // 保存棋谱
                }
            }
            FileChooser fileChooser = new FileChooser(); // 创建弹出窗口
            File file = fileChooser.showOpenDialog(stage); // 弹出保存文件窗口
            GameUtil.readFile(file); // 读取棋谱
            if (!GameUtil.readFile(file)) {
                Alert a = new Alert(Alert.AlertType.INFORMATION);
                a.setHeaderText("棋谱读取失败！");
                a.show();
                return;
            }
            GameConstant.chess.clear(); // 清除list中的棋子
            GameConstant.isEnd = false; // 移除结束判断
            pane.getChildren().clear(); // 清除面板中所有元素
            getCheckerboard(pane, stage);// 重写绘制节点，并加载鼠标点击事件
            if (GameUtil.list.size() == 0) { // 取出的文件为空
                Alert a = new Alert(Alert.AlertType.INFORMATION);
                a.setHeaderText("这个棋谱中没有棋子哦");
                a.show();
            } else { // 取出的文件里有棋子
                pane.getChildren().add(btnPrevious); // 面板中添加上一步按钮
                pane.getChildren().add(btnNext); // 面板中添加下一步按钮
                pane.getChildren().add(btnOut); // 面板中添加退出按钮
                pane.getChildren().add(btnAll); // 面板中添加退出按钮
                /*
                   初始化按钮点击事件
                */
                this.btnNext.setOnMouseClicked(x -> { // 点击下一步时，执行鼠标点击事件
                    if (GameUtil.chessNum == GameUtil.list.size()) { // 判断是否为最后一枚棋子
                        Alert alert = new Alert(Alert.AlertType.INFORMATION);
                        alert.setHeaderText("已经没有棋子咯");
                        alert.show();
                    } else {
                        if (GameUtil.list.get(GameUtil.chessNum).getColor() == 0) {
                            GameUtil.setChess(Color.BLACK, false, pane); // 黑棋
                            GameUtil.chessNum++;// 恢复棋子数量加一
                        } else {
                            GameUtil.setChess(Color.WHITE, true, pane); // 白棋
                            GameUtil.chessNum++;
                        }
                    }
                });
                this.btnPrevious.setOnMouseClicked(x -> { // 点击上一步时执行的鼠标点击事件
                    if (GameUtil.chessNum == 0) { // 判断是否为最后一枚棋子
                        Alert alert = new Alert(Alert.AlertType.INFORMATION);
                        alert.setHeaderText("已经没有棋子咯");
                        alert.show();
                    } else {
                        GameUtil.regretChess(pane);  // 调用移除棋子方法
                        GameUtil.chessNum--; // 记录棋子变量减少
                    }
                });

                this.btnAll.setOnMouseClicked(x -> { // 一键全复盘
                    if (GameUtil.list.size() == 0) {
                        return;
                    }
                    for (int i = 0; i < GameUtil.list.size(); i++) {
                        try {
                            if (GameUtil.list.get(i).getColor() == 0) {
                                GameUtil.setChess(Color.BLACK, false, pane); // 黑棋
                                GameUtil.chessNum++;// 恢复棋子数量加一
                            } else {
                                GameUtil.setChess(Color.WHITE, true, pane); // 白棋
                                GameUtil.chessNum++;
                            }
                        } catch (Exception e1) {
                        }
                    }
                });
                this.btnOut.setOnMouseClicked(x -> { // 点击退出时（打印棋谱）执行的鼠标点击事件
                    pane.getChildren().remove(btnOut); // 移除按钮
                    pane.getChildren().remove(btnNext);
                    pane.getChildren().remove(btnPrevious);
                    pane.getChildren().remove(btnAll);
                });
            }
        });
    }
}
